import React, { useState, useCallback } from 'react'

type ChildProps = {
  click: () => void
}

type Child2Props = {
  count: number
}

const Child1 = ({ click }: ChildProps) => {
  console.log('Child1 组件更新')
  return (
    <div style={{ backgroundColor: 'lightsalmon', padding: 5 }}>
      子组件1：<button onClick={click}>点击</button>
    </div>
  )
}

// React.memo()
// 默认情况下，React.memo 只会对更新前后的 props 进行浅比较 (shallow compare) 与 PureComponent 相同
// 也就是，对对象类型的 prop 来说，只会比较引用
// 如果更新前后的引用相同，复用上一次的渲染结果
// 如果更新前后的引用不同，重现渲染该组件

// 如果想手动控制比较过程，可以使用 React.memo 的第二参数
// 第二个参数：用来比较更新前后 props 的函数
// 返回值：如果返回值是 true，表示不重新渲染该组件，如果返回 false，表示重新渲染该组件
const Child2 = React.memo(
  ({ count }: Child2Props) => {
    console.log('Child2 组件更新')
    return (
      <div style={{ backgroundColor: 'lightgoldenrodyellow', padding: 5 }}>子组件2 -- {count}</div>
    )
  },
  (prevProps, nextProps) => {
    return prevProps === nextProps
  }
)

const App = () => {
  const [count, setCount] = useState(0)

  // 回调函数
  const handleClick = useCallback(() => {
    setCount(count)
  }, [count])

  return (
    <div style={{ backgroundColor: 'lightseagreen', padding: 10 }}>
      <h1>计数器：{count}</h1>
      <button onClick={() => setCount(count + 1)}>+1</button>

      <hr />

      {/* 子组件 */}
      <Child1 click={handleClick} />

      <hr />

      <Child2 count={5} />
    </div>
  )
}

export default App
